<?php

/*
 * $Id: query.php 11 2010-11-24 22:10:53Z LEON $
 * $Author: LEON $
 * $LastChangedDate: 2010-11-24 22:10:53 +0000 (Wed, 24 Nov 2010) $
 * $Revision: 11 $
 */

namespace cmFly\db\sql_constructors;

abstract class query {

    protected $where = Array('logic' => NULL, 'params' => Array());
    protected $pseudo_name;
    protected $user_data;
    private static $counter;
    private $connection;

    public function __construct($connection) {
	$this->connection = $connection;
	$this->gen_new_pseudo_name();
    }

    protected function gen_new_pseudo_name() {
	$this->pseudo_name = '__cmFly_db_table_pseudo' . self::$counter++;
    }

    public function set_user_data($data) {
	$this->user_data = $data;
    }

    public function get_user_data() {
	return $this->user_data;
    }

    public function __clone() {
	$this->gen_new_pseudo_name();
    }

    public function where($where, Array $args=Array()) {
	$this->where = Array('logic' => $where, 'params' => $args);
	return $this;
    }

    protected function build_where() {
	$args = $this->where['params'];
	$table_name = $this->pseudo_name;
	$column_quote_style = $this->get_column_quote_style();
	$obj = $this;
	$res = preg_replace_callback('#([a-z0-9_]*)[\s]*((?:(?:<>|!|<|>)(?:=|)|=)|LIKE|(BETWEEN[\s]*\?[\s]*and))[\s]*\?#si',
			function($matches) use (&$args, $table_name, $column_quote_style, $obj) {
			    $count = count($matches);
			    if (!count($args)) {
				/**
				 * @todo Нормально описать ошибку
				 */
				throw new exception('Args count error!');
			    }
			    $arg = array_shift($args);
			    if ($arg instanceof iExternal_parsed) {
				$arg = $arg->get_value();
			    } elseif (\is_integer($arg) || \is_float($arg)) {
				$arg = $arg;
			    } else {
				$arg = $obj->quote($arg);
			    }

			    switch ($count) {
				case 3:
				    //standart functions
				    return $column_quote_style . $table_name .
				    $column_quote_style . '.' . $column_quote_style .
				    $matches[1] . $column_quote_style .
				    $matches[2] . $arg;
				case 5:
				//BETWEEN
				/**
				 * @todo реализовать between
				 */
			    }
			}, $this->where['logic']);
	if (count($args)) {
	    throw new exception('Args count error!');
	}
	return $res;
    }

    public function get_pseudo_name() {
	return $this->pseudo_name;
    }

    public function quote($var) {
	return $this->get_connection()->quote($var);
    }

    public function get_connection() {
	return $this->connection;
    }

    public function query() {
	return $this->get_connection()->query($this->create_query());
    }

    public function field($field_name) {
	$quote = $this->get_column_quote_style();
	return new field($this, str_replace($quote, '\\' . $quote, $field_name));
    }

    abstract public function create_query();

    abstract public function get_column_quote_style();
}